package com.syty.demo.service.impl;

import com.alibaba.druid.sql.visitor.functions.If;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sun.corba.se.spi.logging.LogWrapperBase;
import com.syty.demo.domain.User;
import com.syty.demo.domain.UserInfo;
import com.syty.demo.exception.MyException;
import com.syty.demo.form.LoginForm;
import com.syty.demo.form.RegisterForm;
import com.syty.demo.form.RemakeForm;
import com.syty.demo.mapper.UserInfoMapper;
import com.syty.demo.mapper.UserMapper;
import com.syty.demo.result.ExceptionResultSet;
import com.syty.demo.result.ResultCodes;
import com.syty.demo.result.ResultSet;
import com.syty.demo.service.UserService;
import com.syty.demo.util.LogUtils;
import com.syty.demo.util.MD5Util;
import com.syty.demo.util.RegexValidateUtil;
import com.syty.demo.util.SaltUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.List;

@Api(value = "用户服务模块")
@Service
public class UserServiceImpl  implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @ApiOperation("登录信息处理器")
    @Override
    public ResultSet login(LoginForm loginForm) {
        //非空校验
        if (loginForm.getUsername()==null||loginForm.getPassword()==null){
            LogUtils.write("[用户登录]--信息为空！");
            LogUtils.write("password:"+loginForm.getPassword()+"username:"+loginForm.getUsername());
            throw new MyException(ExceptionResultSet.USER_LOGIN_INFO_NULL);
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",loginForm.getUsername());
        User user = this.userMapper.selectOne(queryWrapper);
        if (user != null) {
            return new ResultSet(ResultCodes.LOGIN_SUBMIT_SUCCESS,true,"登录成功",user);
        }
        return new ResultSet(ResultCodes.LOGIN_SUBMIT_FAIL,false,"登陆失败",null);
    }

    @ApiOperation("注册处理器")
    @Override
    @Transactional(timeout = 15,rollbackFor = {RuntimeException.class,Exception.class},propagation = Propagation.SUPPORTS)
    public ResultSet register(RegisterForm registerForm) {
        LogUtils.write("Register...");
        //检测用户名是否已存在
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username",registerForm.getRegisterUsername());
        User one = userMapper.selectOne(userQueryWrapper);
        if (one!=null){
            LogUtils.write("[用户注册]--用户名已存在");
            LogUtils.write("用户名【"+ one +"】已存在！");
            throw new MyException(ExceptionResultSet.USER_REGISTER_NAME_ALREADY_EXIST);
        }
        //检测邮箱格式
        if (!RegexValidateUtil.checkEmail(registerForm.getRegisterEmail())){
            LogUtils.write("[用户注册]--邮箱格式错误");
            LogUtils.write("错误的邮箱格式：" + registerForm.getRegisterEmail());
            throw new MyException(ExceptionResultSet.USER_REGISTER_EMAIL_FORMAT_ERROR);
        }
        //保存登录信息
        //创建注册对象
        User user = new User();
        //创建随机盐
        String salt = SaltUtil.getSalt(8);
        //加密
        Md5Hash md5Hash = new Md5Hash(registerForm.getRegisterPassword(),salt ,1024);
        //注册信息
        user.setRole("user");//设置角色  user   /   root
        user.setSalt(salt);
        user.setPassword(md5Hash.toHex());
        user.setUsername(registerForm.getRegisterUsername());
        int insert = userMapper.insert(user);
        if (insert==0){
            LogUtils.write("[用户注册]--保存登录信息失败！");
            throw new MyException(ExceptionResultSet.USER_REGISTER_LOGININFO_SAVE_ERROR);
        }
        //保存用户信息
        String registerUsername = registerForm.getRegisterUsername();
        String registerEmail = registerForm.getRegisterEmail();
        String registerPassword = registerForm.getRegisterPassword();
        UserInfo userInfo = new UserInfo(registerUsername,registerPassword,registerEmail);
        int insert1 = userInfoMapper.insert(userInfo);
        if (insert1==0){
            LogUtils.write("[用户注册]--保存用户信息失败！");
            throw new MyException(ExceptionResultSet.USER_REGISTER_USERINFO_SAVE_ERROR);
        }
        return new ResultSet(ResultCodes.REGISTER_SUBMIT_SUCCESS,true,"注册成功",user);
    }

    /**
     * username email password
     * 首先，查找用户是否存在
     *  如果不存在，抛出异常
     *  如果存在，进行email的比较
     *      比较失败，抛出异常
     *      比较成功，重新设置password
     *  返回结果集成功
     * @param remakeForm
     * @return
     */
    @Override
    @ApiOperation("密码重置处理器")
    @Transactional(timeout = 15,rollbackFor = {RuntimeException.class,Exception.class},propagation = Propagation.SUPPORTS)
    public ResultSet remake(RemakeForm remakeForm) {
        //非空校验
        if (remakeForm.getUsername()==null||remakeForm.getPassword()==null||remakeForm.getEmail()==null){
            LogUtils.write("[重置密码]--信息为空！");
            LogUtils.write("username:" + remakeForm.getUsername() + "email:" + remakeForm.getEmail() + "password:" + remakeForm.getPassword());
            throw new MyException(ExceptionResultSet.USER_REMAKE_INFO_NULL);
        }
        LogUtils.write("Remake...");
        //查询用户是否存在
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", remakeForm.getUsername());
        UserInfo userInfo = userInfoMapper.selectOne(queryWrapper);
        //不存在，抛出异常
        if (userInfo == null){
            LogUtils.write("[重置密码]--信息表用户不存在！");
            LogUtils.write("username:" + remakeForm.getUsername());
            throw new MyException(ExceptionResultSet.USER_REMAKE_USER_NOTEXIST);
        }
        //存在，进行Email比较
        if (!(userInfo.getEmail().equals(remakeForm.getEmail()))) {
            //比较失败，抛出异常
            LogUtils.write("[重置密码]--邮箱不匹配！");
            throw new MyException(ExceptionResultSet.USER_REMAKE_EMAIL_INCOMPATIBLE);
        }
        //比较成功，修改密码
        QueryWrapper<User> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("username", remakeForm.getUsername());
        User user = userMapper.selectOne(queryWrapper1);
        //不存在，抛出异常
        if (user == null){
            LogUtils.write("[重置密码]--登陆表用户不存在！");
            LogUtils.write("username:" + remakeForm.getUsername());
            throw new MyException(ExceptionResultSet.USER_REMAKE_USER_NOTEXIST);
        }
        Md5Hash md5Hash = new Md5Hash(remakeForm.getPassword(), user.getSalt(), 1024);
        String newPassword = md5Hash.toString();
        user.setPassword(newPassword);
        userInfo.setPassword(newPassword);
        return new ResultSet(ResultCodes.REGISTER_SUBMIT_SUCCESS,true,"重置密码成功",user);
    }

    @ApiOperation("提供SHIRO认证，查询数据库用户信息")
    public User findUserByUsername(String username){
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username",username);
        User user = userMapper.selectOne(userQueryWrapper);
        if (!ObjectUtils.isEmpty(user)){
            //如果用户信息存在
            return user;
        }
        //如果用户不存在
        return null;
    }

    @Override
    public String findRoleByUsername(String username) {
        if (username==null){
            LogUtils.write("[SHIRO授权]--用户名为空");
            //抛出异常
        }
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username",username);
        User user = userMapper.selectOne(userQueryWrapper);
        if (user==null){
            LogUtils.write("[SHIRO授权]--信息不存在");
            //抛出异常
        }
        String role = user.getRole();
        if (role==null){
            LogUtils.write("[SHIRO授权]--用户没有角色信息！");
            //抛出异常
        }

        return role;
    }

//    @Override
//    public Integer setStatusByUsernames(String username,int num) {
//        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
//        userQueryWrapper.eq("username",username);
//        User user = userMapper.selectOne(userQueryWrapper);
//        if (!ObjectUtils.isEmpty(user)){
//            UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
//            //如果用户信息存在
//            switch (num){
//                //当前为未登录状态，设置为登录状态
//                case 0:{
//                    userUpdateWrapper.eq("username",username).set("status",1);
//                    LogUtils.write("[登录状态重置]--重置为登录状态");
//                    userMapper.update(null,userUpdateWrapper);
//                    return user.getStatus();
//                }
//                //当前为登录状态，设置为未登录状态
//                case 1:{
//                    userUpdateWrapper.eq("username",username).set("status",0);
//                    userMapper.update(null,userUpdateWrapper);
//                    LogUtils.write("[登录状态重置]--重置为未登录状态");
//                    return user.getStatus();
//                }
//                default:
//                    LogUtils.write("[登录状态重置]--登录状态码判断异常！");
//            }
//        }
//        LogUtils.write("[登录状态重置]--用户为空");
//        return null;
//    }

}
